﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CoolCode.Entities;
using CoolCode.Data.Linq;
using CoolCode.Data.Xml;
using CoolCode.Caching;

namespace CoolCode.Services.LinqToSql
{
    public class CriterionService : ICriterionService
    {
        private static  string _connectionString;
        private readonly string cacheKey = "___ProductCriterion";
        private static ICache criterionCache;

        public CriterionService(string connectionString)
        {
             _connectionString = connectionString;
        }

        public CriterionService(string connectionString, ICache cache)
            : this(connectionString)
        {
            criterionCache = cache;
        }

        #region ICriterionService Members
        
        Func<List<ProductCriterion>> dataProvider = () =>
        {
            using (var context = new XmlContext(_connectionString))
            {
                var table = context.GetTable<ProductCriterion>();
                return table.ToList().OrderBy(c => c.ProductSpec).ToList();
            }
        };

        public List<ProductCriterion> List()
        {
            int oneDay = 3600 * 24;
            List<ProductCriterion> list = null;
            if (criterionCache != null)
            {
                list = criterionCache.Get(cacheKey, dataProvider, oneDay);
            }
            else
            {//if no cache setting, get from database everytime.
                list = dataProvider();
            }
            return list;
        }

        public ProductCriterion Get(string key)
        {
            List<ProductCriterion> list = null;
            if (criterionCache != null)
            {
                list = criterionCache.Get(cacheKey) as List<ProductCriterion>;
                if (list != null)
                    return list.Where(c => c.ProductSpec == key).FirstOrDefault();
            }
             
            using (var context = new XmlContext(_connectionString))
            {
                var table = context.GetTable<ProductCriterion>();
                return table.FirstOrDefault(c => c.ProductSpec == key);
            }
        }

        public void Save(List<ProductCriterion> list)
        {
            using (var context = new XmlContext(_connectionString))
            {
                var table = context.GetTable<ProductCriterion>();
                table.StoreAll(list);
            }
            clearCache();
        }

        public void Save(ProductCriterion entity)
        {
            using (var context = new XmlContext(_connectionString))
            {
                var table = context.GetTable<ProductCriterion>();
                table.Store(entity);
            }
            clearCache();
        }

        private void clearCache()
        {
            if (criterionCache != null)
            { 
                criterionCache.Remove(cacheKey);
            }
        }

        public void SaveDefault()
        {
            using (var context = new XmlContext(_connectionString))
            {
                var table = context.GetTable<ProductCriterion>();
                List<ProductCriterion> list = new List<ProductCriterion>();
                ProductCriterion entity;
                entity = new ProductCriterion
                {
                    ProductSpec = SpecType._22.GetAttachedString(),
                    MinODFar = 3.8m,
                    MaxODFar = 4.0m,
                    MinODClose = 3.8m,
                    MaxODClose = 4.2m,
                    MinConeHeight = 6.00m,
                    MaxConeHeight = 6.70m,
                    MinSacculusLength = 0,
                    MaxSacculusLength = 29,
                    MinSacculusStretch = 48,
                    MaxSacculusStretch = 53,
                    MinODStressTest2 = 20.5m,
                    MaxODStressTest2 = 21.8m,
                    MinStressTestLength = 35.0m,
                    MaxStressTestLength = 37.0m,
                };
                list.Add(entity);

                entity = new ProductCriterion
                {
                    ProductSpec = SpecType._24.GetAttachedString(),
                    MinODFar = 3.8m,
                    MaxODFar = 4.0m,
                    MinODClose = 3.8m,
                    MaxODClose = 4.2m,
                    MinConeHeight = 6.00m,
                    MaxConeHeight = 6.70m,
                    MinSacculusLength = 0,
                    MaxSacculusLength = 29,
                    MinSacculusStretch = 48,
                    MaxSacculusStretch = 53,
                    MinODStressTest2 = 22.5m,
                    MaxODStressTest2 = 23.8m,
                    MinStressTestLength = 37.0m,
                    MaxStressTestLength = 39.0m,
                };
                list.Add(entity);

                entity = new ProductCriterion
                {
                    ProductSpec = SpecType._26.GetAttachedString(),
                    MinODFar = 3.8m,
                    MaxODFar = 4.0m,
                    MinODClose = 3.8m,
                    MaxODClose = 4.2m,
                    MinConeHeight = 6.00m,
                    MaxConeHeight = 6.70m,
                    MinSacculusLength = 0,
                    MaxSacculusLength = 29,
                    MinSacculusStretch = 48,
                    MaxSacculusStretch = 53,
                    MinODStressTest2 = 24.5m,
                    MaxODStressTest2 = 25.8m,
                    MinStressTestLength = 39.0m,
                    MaxStressTestLength = 41.0m,
                };
                list.Add(entity);

                entity = new ProductCriterion
                {
                    ProductSpec = SpecType._28.GetAttachedString(),
                    MinODFar = 3.8m,
                    MaxODFar = 4.1m,
                    MinODClose = 3.8m,
                    MaxODClose = 4.3m,
                    MinConeHeight = 6.10m,
                    MaxConeHeight = 6.70m,
                    MinSacculusLength = 0,
                    MaxSacculusLength = 30,
                    MinSacculusStretch = 48,
                    MaxSacculusStretch = 53,
                    MinODStressTest2 = 26.5m,
                    MaxODStressTest2 = 27.8m,
                    MinStressTestLength = 40.0m,
                    MaxStressTestLength = 42.0m,
                };
                list.Add(entity);

                entity = new ProductCriterion
                {
                    ProductSpec = SpecType._30.GetAttachedString(),
                    MinODFar = 3.8m,
                    MaxODFar = 4.1m,
                    MinODClose = 3.8m,
                    MaxODClose = 4.3m,
                    MinConeHeight = 6.10m,
                    MaxConeHeight = 6.70m,
                    MinSacculusLength = 0,
                    MaxSacculusLength = 30,
                    MinSacculusStretch = 48,
                    MaxSacculusStretch = 53,
                    MinODStressTest2 = 28.5m,
                    MaxODStressTest2 = 29.8m,
                    MinStressTestLength = 41.0m,
                    MaxStressTestLength = 43.0m,
                };
                list.Add(entity);

                table.StoreAll(list);
            }
            clearCache();
        }

        #endregion

    }
}
